package com.learn.training.multithread.chapter9.demo3;

import java.util.concurrent.CompletableFuture;

public class Demo {

    public static void main(String[] args) throws InterruptedException {
        // 两个CompletableFuture执行异步查询
        CompletableFuture<String> cfQueryFromSina = CompletableFuture.supplyAsync(() -> {return QueryCode("中国石油", "https://sina.com");});

        CompletableFuture<String> cfQueryFrom163 = CompletableFuture.supplyAsync(()->{return QueryCode("中国石油", "https://163.com");});

        // 用CompletableFuture.anyOf()方法来合并为一个新的CompletableFuture
        CompletableFuture<Object> cfQuery = CompletableFuture.anyOf(cfQueryFromSina, cfQueryFrom163);
        // 两个CompletableFuture执行异步查询结果
        cfQuery.thenAccept((result) -> {
            System.out.println("result: " + result);
        });

        //两个CompletableFuture执行异步查询
        CompletableFuture<Double> cfFetchFromSina = cfQuery.thenApplyAsync((code) -> {
           return fetchPrice((String) code, "https://sina.com");
        });

        CompletableFuture<Double> cfFetchFrom163 = cfQuery.thenApplyAsync((code) -> {
            return fetchPrice((String) code, "https://163.com");
        });

        // 用CompletableFuture.anyOf()方法来合并为一个新的CompletableFuture
        CompletableFuture<Object> cfFetch = CompletableFuture.anyOf(cfFetchFromSina, cfFetchFrom163);

        // 最终结果
        cfFetch.thenAccept((result) -> {
            System.out.println("Price: " + result);
        });

        // 主进程不要立刻结束，否则CompletableFuture默认使用的线程池会立刻关闭:
        Thread.sleep(2000);

    }

    static String QueryCode(String name, String url) {
        System.out.println("query code from " + url);
        try {
            Thread.sleep((long) (Math.random() * 100));
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        return url + "   " + System.currentTimeMillis();
    }

    static Double fetchPrice(String name, String url) {
        System.out.println("fetch price from " + url);
        try {
            Thread.sleep((long) (Math.random() * 100));
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        return 5 + Math.random() * 20;
    }

}
